package com.cencat.route.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cencat.route.entity.Delivery;
import com.cencat.route.mapper.DeliveryMapper;
import com.cencat.route.service.DeliveryService;
import com.cencat.route.vo.DeliveryQueryVO;
import com.cencat.route.vo.DeliveryStatisticsVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;

/**
 * 配送服务实现类
 * 
 * @author cencat
 * @since 2024-01-01
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class DeliveryServiceImpl extends ServiceImpl<DeliveryMapper, Delivery> implements DeliveryService {

    private final DeliveryMapper deliveryMapper;

    @Override
    public Page<Delivery> selectDeliveryPage(Page<Delivery> page, DeliveryQueryVO query) {
        return deliveryMapper.selectDeliveryPage(page, query);
    }

    @Override
    public List<Delivery> selectDeliveryList(DeliveryQueryVO query) {
        return deliveryMapper.selectDeliveryList(query);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchUpdateDeliveryStatus(List<Long> ids, String status, Long updatedBy) {
        try {
            return deliveryMapper.batchUpdateDeliveryStatus(ids, status, updatedBy) > 0;
        } catch (Exception e) {
            log.error("批量更新配送状态失败: {}", e.getMessage(), e);
            throw new RuntimeException("批量更新配送状态失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchUpdatePriority(List<Long> ids, Integer priority, Long updatedBy) {
        try {
            return deliveryMapper.batchUpdatePriority(ids, priority, updatedBy) > 0;
        } catch (Exception e) {
            log.error("批量更新配送优先级失败: {}", e.getMessage(), e);
            throw new RuntimeException("批量更新配送优先级失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchAssignDeliveryPerson(List<Long> ids, Long deliveryPersonId, Long assignedBy) {
        try {
            return deliveryMapper.batchAssignDeliveryPerson(ids, deliveryPersonId, assignedBy) > 0;
        } catch (Exception e) {
            log.error("批量分配配送员失败: {}", e.getMessage(), e);
            throw new RuntimeException("批量分配配送员失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchUpdateDeliveryFee(List<Long> ids, BigDecimal deliveryFee, Long updatedBy) {
        try {
            return deliveryMapper.batchUpdateDeliveryFee(ids, deliveryFee, updatedBy) > 0;
        } catch (Exception e) {
            log.error("批量更新配送费用失败: {}", e.getMessage(), e);
            throw new RuntimeException("批量更新配送费用失败", e);
        }
    }

    @Override
    public DeliveryStatisticsVO getDeliveryStatistics() {
        try {
            return deliveryMapper.getDeliveryStatistics();
        } catch (Exception e) {
            log.error("获取配送统计信息失败: {}", e.getMessage(), e);
            throw new RuntimeException("获取配送统计信息失败", e);
        }
    }

    @Override
    public String intelligentMatchDelivery(String requirements) {
        try {
            return deliveryMapper.intelligentMatchDelivery(requirements);
        } catch (Exception e) {
            log.error("智能匹配配送失败: {}", e.getMessage(), e);
            throw new RuntimeException("智能匹配配送失败", e);
        }
    }

    @Override
    public List<Delivery> getUrgentDeliveries(Integer limit) {
        try {
            return deliveryMapper.getUrgentDeliveries(limit);
        } catch (Exception e) {
            log.error("获取紧急配送列表失败: {}", e.getMessage(), e);
            throw new RuntimeException("获取紧急配送列表失败", e);
        }
    }

    @Override
    public List<Delivery> getPendingDeliveries(Integer limit) {
        try {
            return deliveryMapper.getPendingDeliveries(limit);
        } catch (Exception e) {
            log.error("获取待处理配送列表失败: {}", e.getMessage(), e);
            throw new RuntimeException("获取待处理配送列表失败", e);
        }
    }

    @Override
    public List<Delivery> getActiveDeliveries(Integer limit) {
        try {
            return deliveryMapper.getActiveDeliveries(limit);
        } catch (Exception e) {
            log.error("获取活跃配送列表失败: {}", e.getMessage(), e);
            throw new RuntimeException("获取活跃配送列表失败", e);
        }
    }

    @Override
    public List<Delivery> getCompletedDeliveries(Integer limit) {
        try {
            return deliveryMapper.getCompletedDeliveries(limit);
        } catch (Exception e) {
            log.error("获取已完成配送列表失败: {}", e.getMessage(), e);
            throw new RuntimeException("获取已完成配送列表失败", e);
        }
    }

    @Override
    public List<Delivery> getHighPriorityDeliveries(Integer minPriority, Integer limit) {
        try {
            return deliveryMapper.getHighPriorityDeliveries(minPriority, limit);
        } catch (Exception e) {
            log.error("获取高优先级配送列表失败: {}", e.getMessage(), e);
            throw new RuntimeException("获取高优先级配送列表失败", e);
        }
    }

    @Override
    public List<Delivery> getNewCreatedDeliveries(Integer hours, Integer limit) {
        try {
            return deliveryMapper.getNewCreatedDeliveries(hours, limit);
        } catch (Exception e) {
            log.error("获取新创建配送列表失败: {}", e.getMessage(), e);
            throw new RuntimeException("获取新创建配送列表失败", e);
        }
    }

    @Override
    public boolean checkDeliveryExists(Long id) {
        try {
            return deliveryMapper.checkDeliveryExists(id) > 0;
        } catch (Exception e) {
            log.error("检查配送是否存在失败: {}", e.getMessage(), e);
            return false;
        }
    }

    @Override
    public boolean checkDeliveryCodeExists(String deliveryCode, Long excludeId) {
        try {
            return deliveryMapper.checkDeliveryCodeExists(deliveryCode, excludeId) > 0;
        } catch (Exception e) {
            log.error("检查配送编码是否存在失败: {}", e.getMessage(), e);
            return false;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean createDelivery(Delivery delivery) {
        try {
            // 检查配送编码是否已存在
            if (checkDeliveryCodeExists(delivery.getDeliveryCode(), null)) {
                throw new RuntimeException("配送编码已存在");
            }
            
            // 设置默认值
            delivery.setStatus("PENDING");
            delivery.setPriority(1);
            
            return save(delivery);
        } catch (Exception e) {
            log.error("创建配送失败: {}", e.getMessage(), e);
            throw new RuntimeException("创建配送失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateDeliveryInfo(Long deliveryId, String description, Integer priority, Long updatedBy) {
        try {
            return deliveryMapper.updateDeliveryInfo(deliveryId, description, priority, updatedBy) > 0;
        } catch (Exception e) {
            log.error("更新配送信息失败: {}", e.getMessage(), e);
            throw new RuntimeException("更新配送信息失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean assignDelivery(Long deliveryId, Long deliveryPersonId, Long assignedBy) {
        try {
            return deliveryMapper.assignDelivery(deliveryId, deliveryPersonId, assignedBy) > 0;
        } catch (Exception e) {
            log.error("分配配送失败: {}", e.getMessage(), e);
            throw new RuntimeException("分配配送失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean startDelivery(Long deliveryId, Long startedBy) {
        try {
            return deliveryMapper.startDelivery(deliveryId, startedBy) > 0;
        } catch (Exception e) {
            log.error("开始配送失败: {}", e.getMessage(), e);
            throw new RuntimeException("开始配送失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean completeDelivery(Long deliveryId, String completionNotes, Long completedBy) {
        try {
            return deliveryMapper.completeDelivery(deliveryId, completionNotes, completedBy) > 0;
        } catch (Exception e) {
            log.error("完成配送失败: {}", e.getMessage(), e);
            throw new RuntimeException("完成配送失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean cancelDelivery(Long deliveryId, String cancelReason, Long cancelledBy) {
        try {
            return deliveryMapper.cancelDelivery(deliveryId, cancelReason, cancelledBy) > 0;
        } catch (Exception e) {
            log.error("取消配送失败: {}", e.getMessage(), e);
            throw new RuntimeException("取消配送失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean pauseDelivery(Long deliveryId, String pauseReason, Long pausedBy) {
        try {
            return deliveryMapper.pauseDelivery(deliveryId, pauseReason, pausedBy) > 0;
        } catch (Exception e) {
            log.error("暂停配送失败: {}", e.getMessage(), e);
            throw new RuntimeException("暂停配送失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean resumeDelivery(Long deliveryId, Long resumedBy) {
        try {
            return deliveryMapper.resumeDelivery(deliveryId, resumedBy) > 0;
        } catch (Exception e) {
            log.error("恢复配送失败: {}", e.getMessage(), e);
            throw new RuntimeException("恢复配送失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateDeliveryProgress(Long deliveryId, Integer progress, String progressNotes, Long updatedBy) {
        try {
            return deliveryMapper.updateDeliveryProgress(deliveryId, progress, progressNotes, updatedBy) > 0;
        } catch (Exception e) {
            log.error("更新配送进度失败: {}", e.getMessage(), e);
            throw new RuntimeException("更新配送进度失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateDeliveryLocation(Long deliveryId, String currentLocation, BigDecimal latitude, BigDecimal longitude, Long updatedBy) {
        try {
            return deliveryMapper.updateDeliveryLocation(deliveryId, currentLocation, latitude, longitude, updatedBy) > 0;
        } catch (Exception e) {
            log.error("更新配送位置失败: {}", e.getMessage(), e);
            throw new RuntimeException("更新配送位置失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateDeliverySchedule(Long deliveryId, String scheduledStartTime, String scheduledEndTime, Long updatedBy) {
        try {
            return deliveryMapper.updateDeliverySchedule(deliveryId, scheduledStartTime, scheduledEndTime, updatedBy) > 0;
        } catch (Exception e) {
            log.error("更新配送计划失败: {}", e.getMessage(), e);
            throw new RuntimeException("更新配送计划失败", e);
        }
    }

    @Override
    public String analyzeDeliveryPerformance(Long deliveryId, String startDate, String endDate) {
        try {
            return deliveryMapper.analyzeDeliveryPerformance(deliveryId, startDate, endDate);
        } catch (Exception e) {
            log.error("分析配送性能失败: {}", e.getMessage(), e);
            throw new RuntimeException("分析配送性能失败", e);
        }
    }

    @Override
    public String generateDeliveryReport(Long deliveryId, String reportType) {
        try {
            return deliveryMapper.generateDeliveryReport(deliveryId, reportType);
        } catch (Exception e) {
            log.error("生成配送报告失败: {}", e.getMessage(), e);
            throw new RuntimeException("生成配送报告失败", e);
        }
    }

    @Override
    public String exportDeliveryData(DeliveryQueryVO query, String exportFormat) {
        try {
            return deliveryMapper.exportDeliveryData(query, exportFormat);
        } catch (Exception e) {
            log.error("导出配送数据失败: {}", e.getMessage(), e);
            throw new RuntimeException("导出配送数据失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String importDeliveryData(String importData, Long importedBy) {
        try {
            return deliveryMapper.importDeliveryData(importData, importedBy);
        } catch (Exception e) {
            log.error("导入配送数据失败: {}", e.getMessage(), e);
            throw new RuntimeException("导入配送数据失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchProcessDeliveries(List<Long> deliveryIds, String processType, Long processedBy) {
        try {
            return deliveryMapper.batchProcessDeliveries(deliveryIds, processType, processedBy) > 0;
        } catch (Exception e) {
            log.error("批量处理配送失败: {}", e.getMessage(), e);
            throw new RuntimeException("批量处理配送失败", e);
        }
    }

    @Override
    public String getDeliveryRecommendations(Long deliveryId) {
        try {
            return deliveryMapper.getDeliveryRecommendations(deliveryId);
        } catch (Exception e) {
            log.error("获取配送推荐失败: {}", e.getMessage(), e);
            throw new RuntimeException("获取配送推荐失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean recordDeliveryEvent(Long deliveryId, String eventType, String eventDescription, Long recordedBy) {
        try {
            return deliveryMapper.recordDeliveryEvent(deliveryId, eventType, eventDescription, recordedBy) > 0;
        } catch (Exception e) {
            log.error("记录配送事件失败: {}", e.getMessage(), e);
            throw new RuntimeException("记录配送事件失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateDeliveryRating(Long deliveryId, BigDecimal rating, String feedback, Long ratedBy) {
        try {
            return deliveryMapper.updateDeliveryRating(deliveryId, rating, feedback, ratedBy) > 0;
        } catch (Exception e) {
            log.error("更新配送评分失败: {}", e.getMessage(), e);
            throw new RuntimeException("更新配送评分失败", e);
        }
    }

    @Override
    public String getDeliveryAlternatives(Long deliveryId, Integer maxAlternatives) {
        try {
            return deliveryMapper.getDeliveryAlternatives(deliveryId, maxAlternatives);
        } catch (Exception e) {
            log.error("获取配送替代方案失败: {}", e.getMessage(), e);
            throw new RuntimeException("获取配送替代方案失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean optimizeDelivery(Long deliveryId, String optimizationType, Long optimizedBy) {
        try {
            return deliveryMapper.optimizeDelivery(deliveryId, optimizationType, optimizedBy) > 0;
        } catch (Exception e) {
            log.error("优化配送失败: {}", e.getMessage(), e);
            throw new RuntimeException("优化配送失败", e);
        }
    }

    @Override
    public String validateDelivery(Long deliveryId) {
        try {
            return deliveryMapper.validateDelivery(deliveryId);
        } catch (Exception e) {
            log.error("验证配送失败: {}", e.getMessage(), e);
            throw new RuntimeException("验证配送失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean archiveDelivery(Long deliveryId, String archiveReason, Long archivedBy) {
        try {
            return deliveryMapper.archiveDelivery(deliveryId, archiveReason, archivedBy) > 0;
        } catch (Exception e) {
            log.error("归档配送失败: {}", e.getMessage(), e);
            throw new RuntimeException("归档配送失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean restoreDelivery(Long deliveryId, Long restoredBy) {
        try {
            return deliveryMapper.restoreDelivery(deliveryId, restoredBy) > 0;
        } catch (Exception e) {
            log.error("恢复配送失败: {}", e.getMessage(), e);
            throw new RuntimeException("恢复配送失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean cloneDelivery(Long sourceDeliveryId, String newDeliveryCode, Long clonedBy) {
        try {
            return deliveryMapper.cloneDelivery(sourceDeliveryId, newDeliveryCode, clonedBy) > 0;
        } catch (Exception e) {
            log.error("克隆配送失败: {}", e.getMessage(), e);
            throw new RuntimeException("克隆配送失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean mergeDeliveries(List<Long> deliveryIds, String newDeliveryCode, Long mergedBy) {
        try {
            return deliveryMapper.mergeDeliveries(deliveryIds, newDeliveryCode, mergedBy) > 0;
        } catch (Exception e) {
            log.error("合并配送失败: {}", e.getMessage(), e);
            throw new RuntimeException("合并配送失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean splitDelivery(Long deliveryId, String splitConfig, Long splitBy) {
        try {
            return deliveryMapper.splitDelivery(deliveryId, splitConfig, splitBy) > 0;
        } catch (Exception e) {
            log.error("拆分配送失败: {}", e.getMessage(), e);
            throw new RuntimeException("拆分配送失败", e);
        }
    }

    @Override
    public String calculateDeliveryCost(Long deliveryId) {
        try {
            return deliveryMapper.calculateDeliveryCost(deliveryId);
        } catch (Exception e) {
            log.error("计算配送成本失败: {}", e.getMessage(), e);
            throw new RuntimeException("计算配送成本失败", e);
        }
    }

    @Override
    public Integer estimateDeliveryTime(Long deliveryId) {
        try {
            return deliveryMapper.estimateDeliveryTime(deliveryId);
        } catch (Exception e) {
            log.error("预估配送时间失败: {}", e.getMessage(), e);
            throw new RuntimeException("预估配送时间失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateDeliveryStatistics(Long deliveryId, Long updatedBy) {
        try {
            return deliveryMapper.updateDeliveryStatistics(deliveryId, updatedBy) > 0;
        } catch (Exception e) {
            log.error("更新配送统计信息失败: {}", e.getMessage(), e);
            throw new RuntimeException("更新配送统计信息失败", e);
        }
    }

    @Override
    public String getDeliveryHistory(Long deliveryId) {
        try {
            return deliveryMapper.getDeliveryHistory(deliveryId);
        } catch (Exception e) {
            log.error("获取配送历史失败: {}", e.getMessage(), e);
            throw new RuntimeException("获取配送历史失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean notifyDeliveryUpdate(Long deliveryId, String notificationType, String message, Long notifiedBy) {
        try {
            return deliveryMapper.notifyDeliveryUpdate(deliveryId, notificationType, message, notifiedBy) > 0;
        } catch (Exception e) {
            log.error("通知配送更新失败: {}", e.getMessage(), e);
            throw new RuntimeException("通知配送更新失败", e);
        }
    }

    @Override
    public String getDeliveryMetrics(Long deliveryId, String metricsType) {
        try {
            return deliveryMapper.getDeliveryMetrics(deliveryId, metricsType);
        } catch (Exception e) {
            log.error("获取配送指标失败: {}", e.getMessage(), e);
            throw new RuntimeException("获取配送指标失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean escalateDelivery(Long deliveryId, String escalationReason, Long escalatedBy) {
        try {
            return deliveryMapper.escalateDelivery(deliveryId, escalationReason, escalatedBy) > 0;
        } catch (Exception e) {
            log.error("升级配送失败: {}", e.getMessage(), e);
            throw new RuntimeException("升级配送失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deescalateDelivery(Long deliveryId, String deescalationReason, Long deescalatedBy) {
        try {
            return deliveryMapper.deescalateDelivery(deliveryId, deescalationReason, deescalatedBy) > 0;
        } catch (Exception e) {
            log.error("降级配送失败: {}", e.getMessage(), e);
            throw new RuntimeException("降级配送失败", e);
        }
    }

}